package models;

import java.util.LinkedList;
import java.util.List;

import javax.persistence.*;

import controllers.Security;

import play.db.jpa.Model;

@Entity
@Table(name = "Task_Statuses")
public class TaskStatus extends Model {
	public String status;

	@OneToMany(mappedBy = "status")
	public List<Task> tasks = new LinkedList<Task>();

	@OneToMany(mappedBy = "status", cascade = { CascadeType.REMOVE })
	public List<BoardColumn> columns = new LinkedList<BoardColumn>();

	@ManyToOne
	public Project project;

	public boolean isSystem;

	public TaskStatus(String name, boolean isSystem) {
		this.isSystem = isSystem;
		this.status = name;
	}

	public TaskStatus(String name, Project project) {
		this.isSystem = false;
		this.status = name;
		this.project = project;
	}

	/**
	 * constructs a new task status
	 * 
	 * @param name
	 */
	public TaskStatus(String name) {
		this.status = name;
	}

	/**
	 * changes the name of a task status
	 * 
	 * @param newName
	 */
	public void changeName(String newName) {
		this.status = newName;
		save();
	}

	public TaskStatus delete() {

		for (Task task : tasks) {
			task.status = null;
			task.save();
		}

		return super.delete();
	}

	/**
	 * This method gets a list of all Task Statuses in the system.
	 * 
	 * @return List<TaskStatus>
	 * */
	public static List<TaskStatus> getAllTaskStatuses() {
		List<TaskStatus> allTaskStatuses = TaskStatus.all().fetch();

		int i = 0;
		while (i < allTaskStatuses.size()) {
			if (allTaskStatuses.get(i).isSystem == false)
				allTaskStatuses.remove(allTaskStatuses.get(i));
			else
				i++;
		}

		return allTaskStatuses;
	}

	/**
	 * Given a task status id and a name, this method changes the name of the
	 * Task Status with the given id. No duplicate names allowed.
	 * 
	 * @param id
	 * @param name
	 * 
	 * @return boolean
	 */
	public boolean changeTaskStatusName(long projectId, String name,
			boolean isSystem) {
		Project project = Project.findById(projectId);

		List<TaskStatus> list = new LinkedList<TaskStatus>();
		if (isSystem)
			list = TaskStatus.getAllTaskStatuses();
		else
			list = project.taskStatuses;

		boolean found = false;
		int size = list.size();
		for (int i = 0; i < size; i++) {
			if (list.get(i).status.equals(name))
				found = true;
		}
		if (!found) {
			this.changeName(name);
			return true;
		} else
			return false;

	}

	/**
	 * Given a task status name, a project id, this method creates a new task
	 * status and adds it to the system. The status is added to the given
	 * project if the isSystem is false. No duplicate names allowed.
	 * 
	 * @param projectId
	 * @param name
	 * @param isSystem
	 * 
	 * @return boolean
	 */
	public static boolean createTaskStatus(long projectId, String name,
			boolean isSystem) {

		Project project = Project.findById(projectId);
		boolean found = false;
		if (!isSystem) {

			for (int i = 0; i < project.taskStatuses.size(); i++)
				if (project.taskStatuses.get(i).status.equals(name))
					found = true;

			if (!found && !name.equals("") && name != null) {
				TaskStatus status = new TaskStatus(name, project);
				status.save();
				project.taskStatuses.add(status);
				project.save();
				return true;
			} else
				return false;

		} else {
			List<TaskStatus> list = TaskStatus.getAllTaskStatuses();
			int size = list.size();
			for (int i = 0; i < size; i++)
				if (list.get(i).status.equals(name))
					found = true;

			TaskStatus status = new TaskStatus(name, isSystem);
			if (!found && !name.equals("") && name != null) {
				status.save();
				return true;
			} else {
				return false;
			}
		}

	}
}
